package com.online.questionnaire.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.online.questionnaire.common.ErrorCode;
import com.online.questionnaire.common.PageParam;
import com.online.questionnaire.common.R;
import com.online.questionnaire.common.ResultUtils;
import com.online.questionnaire.exception.BusinessException;
import com.online.questionnaire.exception.ThrowUtils;
import com.online.questionnaire.model.User;
import com.online.questionnaire.model.vo.UserReg;
import com.online.questionnaire.service.UserService;
import com.online.questionnaire.utils.PwdUtil;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import static com.online.questionnaire.constant.UserConstant.*;

/**
 * 用户接口
 */
@RestController
@RequestMapping("/user")
@Slf4j
@Tag(name = "用户接口")
public class UserController extends BaseController<User>{

    @Resource
    private UserService userService;


    /**
     * 分页查询
     * @param param
     * @param obj
     * @return
     */
    @GetMapping("/page")
    @Override
    public R<IPage<User>> page(PageParam param, User obj, HttpServletRequest request) {
        if (param == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        if (param.getPage() == null || param.getPage() <= 0){
            param.setPage(1);
        }
        if (param.getSize() == null || param.getSize() <= 0 || param.getSize() > 100){
            param.setSize(10);
        }
        if (userService.getLoginUser(request) == null){
            ThrowUtils.notLoginError();
        }

        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        // 模糊查询 用户名或账号
        queryWrapper.like(StringUtils.isNotBlank(obj.getUserName()),User::getUserAccount,obj.getUserName())
                .or().like(StringUtils.isNotBlank(obj.getUserName()),User::getUserName,obj.getUserName());

        queryWrapper.eq(StringUtils.isNotBlank(obj.getUserRole()),User::getUserRole,obj.getUserRole());
        IPage<User> page = getService().page(new Page(param.getPage(), param.getSize()), queryWrapper);
        return ResultUtils.success(page);
    }


    @PostMapping("/register")
    public R<Boolean> register(@RequestBody UserReg regUser) {
        if (StringUtils.isAllBlank(regUser.getUserAccount(),
                regUser.getUserPassword(),regUser.getCheckPassword())){
            ThrowUtils.paramsError("帐号或密码不能为空");
        }
        if (!regUser.getUserPassword().equals(regUser.getCheckPassword())){
            ThrowUtils.paramsError("密码不一致");
        }
        User user = new User();
        BeanUtils.copyProperties(regUser, user);
        int register = userService.register(user);
        return ResultUtils.success(register > 0);
    }

    @PostMapping("/login")
    public R<User> login(@RequestBody UserReg loginUser, HttpServletRequest request){
        if (StringUtils.isAllBlank(loginUser.getUserAccount(),
                loginUser.getUserPassword())){
            ThrowUtils.paramsError("帐号或密码不能为空");
        }
        User user = new User();
        BeanUtils.copyProperties(loginUser, user);
        User login = userService.login(user);
        if (login != null){
            if (BAN_ROLE.equals(login.getUserRole())){
                ThrowUtils.throwIf(true,ErrorCode.NO_AUTH_ERROR,"用户已被封禁");
            }
            //登录状态写入session中
            request.getSession().setAttribute(USER_LOGIN_STATE,login.getId());
        }
        return ResultUtils.success(login);
    }

    @GetMapping("/current")
    public R<User> current(HttpServletRequest request){
        Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
        if (userObj == null){
            ThrowUtils.notLoginError();
        }
        User currentUser = userService.getLoginUser(request);
        return ResultUtils.success(currentUser);
    }

    /**
     * 退出登录
     * @param request
     * @return
     */
    @GetMapping("/logout")
    public R<Boolean> logout(HttpServletRequest request){
        request.getSession().removeAttribute(USER_LOGIN_STATE);
        return ResultUtils.success(true);
    }

    @Override
    public R<Boolean> add(@RequestBody User obj, HttpServletRequest request) {
        if (obj == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //检查是否为管理员
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null){
            ThrowUtils.notLoginError();
        }
        if (!ADMIN_ROLE.equals(loginUser.getUserRole())){
            return ResultUtils.error(ErrorCode.NO_AUTH_ERROR);
        }
        if (StringUtils.isBlank(obj.getUserAccount())){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"帐号不能为空");
        }
        //检查账号是否存在
        var userQuery = new LambdaQueryWrapper<User>();
        userQuery.eq(User::getUserAccount, obj.getUserAccount());
        if (userService.exists(userQuery)){
            throw new BusinessException(ErrorCode.OPERATION_ERROR,"帐号已存在");
        }
        if (StringUtils.isBlank(obj.getUserName())){
            obj.setUserName(obj.getUserAccount());
        }
        if (StringUtils.isBlank(obj.getUserRole())){
            obj.setUserRole(DEFAULT_ROLE);
        }

        //加密密码
        if (StringUtils.isNotBlank(obj.getUserPassword())){
            obj.setUserPassword(PwdUtil.toMD5_SALT(obj.getUserPassword()));
        }else{
            obj.setUserPassword(null);
        }
        return super.add(obj, request);
    }

    @Override
    public R<Boolean> update(@RequestBody User obj, HttpServletRequest request) {
        //检查是否为自身或者管理员
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null){
            ThrowUtils.notLoginError();
        }
        if (!loginUser.getId().equals(obj.getId())
                && !ADMIN_ROLE.equals(loginUser.getUserRole())){
            return ResultUtils.error(ErrorCode.NO_AUTH_ERROR);
        }
        //加密密码
        if (StringUtils.isNotBlank(obj.getUserPassword())){
            obj.setUserPassword(PwdUtil.toMD5_SALT(obj.getUserPassword()));
        }else{
            obj.setUserPassword(null);
        }

        return super.update(obj, request);
    }

    @GetMapping("/delete/{id}")
    public R<Boolean> delete(@PathVariable Long id, HttpServletRequest request) {
        if (id == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //检查是否管理员
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null){
            ThrowUtils.notLoginError();
        }
        if (!ADMIN_ROLE.equals(loginUser.getUserRole())){
            return ResultUtils.error(ErrorCode.NO_AUTH_ERROR);
        }
        boolean remove = getService().removeById(id);
        if (!remove){
            return ResultUtils.error(ErrorCode.OPERATION_ERROR);
        }
        return ResultUtils.success(remove);
    }

    @PostMapping("/ex")
    public R<String> ex() {
        throw new BusinessException(ErrorCode.SYSTEM_ERROR,"业务异常");
    }

    @Override
    protected IService<User> getService() {
        return userService;
    }

    @Override
    protected UserService getUserService() {
        return userService;
    }
}
